package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.zhijian.medical.config.CommonConfig;
import com.zhijian.medical.config.Constants;
import com.zhijian.medical.dao.local.PcrKzyMapper;
import com.zhijian.medical.entity.UploadParam;
import com.zhijian.medical.entity.dto.PcrHskzyqWzDto;
import com.zhijian.medical.entity.dto.PcrResultDto;
import com.zhijian.medical.entity.po.*;
import com.zhijian.medical.entity.vo.request.ExperimentProcessSampleSearchVo;
import com.zhijian.medical.entity.vo.request.PcrKzySearchVo;
import com.zhijian.medical.entity.vo.request.PcrResultSearchVo;
import com.zhijian.medical.entity.vo.response.*;
import com.zhijian.medical.enums.*;
import com.zhijian.medical.service.*;
import com.zhijian.medical.util.AssertUtil;
import com.zhijian.medical.util.JsonUtil;
import com.zhijian.medical.util.Page;
import com.zhijian.medical.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 荧光PCR-核酸扩增一区-扩增仪数据业务处理层
 *
 * @author HCG
 * @version: 1.0
 * @date 2022-08-31 10:10:14
 */
@Slf4j
@Service
public class PcrKzyServiceImpl implements PcrKzyService {

    @Autowired
    private PcrKzyMapper mapper;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private PcrResultService pcrResultService;

    @Autowired
    private PcrResultDetailService pcrResultDetailService;

    @Autowired
    private PcrService pcrService;

    @Autowired
    private ExperimentProcessSampleService experimentProcessSampleService;

    @Autowired
    private UploadParam uploadParam;

    @Autowired
    private CommonConfig commonConfig;

    @Override
    public PcrKzy selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public PcrKzy selectByPcrIdAndDeviceId(Long pcrId, Long deviceId) {
        return mapper.selectByPcrIdAndDeviceId(pcrId, deviceId);
    }

    @Override
    public PcrKzyVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public void deleteByPcrId(Long pcrId) {
        mapper.deleteByPcrId(pcrId);
    }

    @Override
    public Long insert(PcrKzy pcrKzy) {
        Date now = new Date();
        pcrKzy.setCreateTime(now);
        pcrKzy.setUpdateTime(now);
        pcrKzy.setKjhzj(StatusEnum.NORMAL.getCode().byteValue());
        pcrKzy.setAzsopjxbccssd(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrKzy.setYqsyzt(StatusEnum.NORMAL.getCode().byteValue());
        pcrKzy.setJgpdyxsnzksfwr(StatusEnum.UN_NORMAL.getCode().byteValue());
        pcrKzy.setJgpdyxsnzksfzk(StatusEnum.NORMAL.getCode().byteValue());
        return mapper.insert(pcrKzy) > 0 ? pcrKzy.getId() : 0L;
    }

    @Override
    public boolean update(PcrKzy pcrKzy) {
        Date now = new Date();
        pcrKzy.setUpdateTime(now);
        return mapper.updateByPrimaryKey(pcrKzy) != 0;
    }

    @Override
    public Integer count(PcrKzySearchVo pcrKzySearchVo) {
        return mapper.count(pcrKzySearchVo);
    }

    @Override
    public List<PcrKzyVo> selectList(PcrKzySearchVo pcrKzySearchVo) {
        return mapper.selectList(pcrKzySearchVo);
    }

    @Override
    public Page<PcrKzyVo> selectPage(PcrKzySearchVo pcrKzySearchVo) {
        //先直接查总数
        int count = count(pcrKzySearchVo);
        //分页
        Page<PcrKzyVo> page = new Page<>(true, count, pcrKzySearchVo.getPageNum(), pcrKzySearchVo.getPageSize());
        pcrKzySearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<PcrKzyVo> responseVos = this.selectList(pcrKzySearchVo);
        page.setData(responseVos);
        return page;
    }

    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public boolean importExcel(Long pcrId, Long deviceId, MultipartFile file) {
        Pcr pcr = pcrService.selectById(pcrId);
        AssertUtil.notNull(pcr, "此实验流程不存在或者已被删除");
        Device device = deviceService.selectById(deviceId);
        AssertUtil.notNull(device, "此扩增仪不存在或者已被删除");

        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Date now = new Date();

        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<List<Object>> listList = reader.read(8);
        if (pcr.getType() == PcrTypeEnum.COV.getCode().byteValue()) {
            //如果是新冠病毒流程，则要判断一个样本只能放置于一个反应孔位置
            List<String> noRepeat = listList.stream().map(l -> (String) l.get(1)).distinct().collect(Collectors.toList());
            AssertUtil.check(noRepeat.size() * 2 != listList.size(), "一个样本只能放置于一个反应孔位置");
        }

        Set<String> valueSet = Sets.newHashSet();
        PcrHskzyqWzDto initValue = new PcrHskzyqWzDto();
        List<PcrHskzyqWzDto> A = Lists.newArrayList(initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue);
        List<PcrHskzyqWzDto> B = Lists.newArrayList(initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue);
        List<PcrHskzyqWzDto> C = Lists.newArrayList(initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue);
        List<PcrHskzyqWzDto> D = Lists.newArrayList(initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue);
        List<PcrHskzyqWzDto> E = Lists.newArrayList(initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue);
        List<PcrHskzyqWzDto> F = Lists.newArrayList(initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue);
        List<PcrHskzyqWzDto> G = Lists.newArrayList(initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue);
        List<PcrHskzyqWzDto> H = Lists.newArrayList(initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue, initValue);
        List<ExperimentProcessSampleVo> experimentProcessSampleVos = experimentProcessSampleService.selectList(ExperimentProcessSampleSearchVo.builder()
                .mainType(ExperimentTypeEnum.PCR.getCode().byteValue())
                .experimentProcessId(pcrId)
                .build());

        List<List<PcrHskzyqWzDto>> finalList = Lists.newArrayList(null, null, null, null, null, null, null, null);
        for (List<Object> l : listList) {
            AssertUtil.check(Objects.isNull(l.get(0)) || StringUtils.isBlank((String) l.get(0)), "反应孔不能为空");
            AssertUtil.check(Objects.isNull(l.get(1)) || StringUtils.isBlank((String) l.get(1)), "样本名不能为空");
            AssertUtil.check(Objects.isNull(l.get(2)) || StringUtils.isBlank((String) l.get(2)), "基因名称不能为空");
            AssertUtil.check(Objects.isNull(l.get(3)) || StringUtils.isBlank((String) l.get(3)), "任务不能为空");
            AssertUtil.check(Objects.isNull(l.get(4)) || StringUtils.isBlank((String) l.get(4)), "报告基因不能为空");
            AssertUtil.check(Objects.isNull(l.get(5)) || StringUtils.isBlank((String) l.get(5)), "猝灭基因不能为空");
            AssertUtil.check(Objects.isNull(l.get(6)) || StringUtils.isBlank(l.get(6) + "") || StrUtil.isNullStr(l.get(6) + ""), "Ct不能为空");
            AssertUtil.check((Objects.isNull(l.get(7)) || StringUtils.isBlank(l.get(7) + "") || StrUtil.isNullStr(l.get(7) + "") || !NumberUtil.isNumber(l.get(7) + "")) && !((String) l.get(1)).startsWith(Constants.Pcr.NTC) && !((String) l.get(1)).startsWith(Constants.Pcr.STD), "Ct平均值不能为空且只能为数字");
            AssertUtil.check(Objects.isNull(l.get(12)) || StringUtils.isBlank(l.get(12) + "") || StrUtil.isNullStr(l.get(12) + ""), "自动 Ct 阈值不能为空");
            AssertUtil.check(Objects.isNull(l.get(13)) || StringUtils.isBlank(l.get(13) + "") || StrUtil.isNullStr(l.get(13) + "") || !NumberUtil.isNumber(l.get(13) + ""), "Ct阈值不能为空且只能为数字");
            AssertUtil.check(Objects.isNull(l.get(14)) || StringUtils.isBlank(l.get(14) + "") || StrUtil.isNullStr(l.get(14) + ""), "自动基线不能为空");
            AssertUtil.check(Objects.isNull(l.get(15)) || StringUtils.isBlank(l.get(15) + "") || StrUtil.isNullStr(l.get(15) + "") || !NumberUtil.isNumber(l.get(15) + ""), "基线起点不能为空且只能为数字");
            AssertUtil.check(Objects.isNull(l.get(16)) || StringUtils.isBlank(l.get(16) + "") || StrUtil.isNullStr(l.get(16) + "") || !NumberUtil.isNumber(l.get(16) + ""), "基线终点不能为空且只能为数字");
            AssertUtil.check(Objects.isNull(l.get(18)) || StringUtils.isBlank(l.get(18) + "") || StrUtil.isNullStr(l.get(18) + ""), "HIGHSD不能为空");
            //位置
            String position = ((String) l.get(0)).substring(0, 1);
            //分子病理号与项目的组合
            String fzlbhAndProject = (String) l.get(1);
            String[] fzlbhAndProjectAry = fzlbhAndProject.split("-");
            AssertUtil.check(fzlbhAndProjectAry.length < 2, "有不符合的的样本名，请检查后重写填写");
            //分子病理号
            String fzblh = fzlbhAndProjectAry[0];
            //是不是对照组
            boolean weatherDzz = fzblh.equals(Constants.Pcr.NTC) || fzblh.equals(Constants.Pcr.STD);
//            if (fzblh.equals(Constants.Pcr.NTC) || fzblh.equals(Constants.Pcr.STD)) {
//                //如果是NTC/STD，越过循环
//                continue;
//            }
            //项目
            String project = fzlbhAndProjectAry[1];
            PcrHskzyqWzDto pcrHskzyqWzDto = new PcrHskzyqWzDto();
            //找出这个样本的信息
            if (!weatherDzz) {
                ExperimentProcessSampleVo experimentProcessSampleVo = experimentProcessSampleVos.stream().filter(e -> e.getMoleculePathologyNumber().equals(fzblh)).findFirst().orElse(null);
                AssertUtil.notNull(experimentProcessSampleVo, String.format("分子病理号为%s的样本不存在", fzblh));
                AssertUtil.check(!Objects.equals(experimentProcessSampleVo.getExperimentProcessId(), pcrId), String.format("分子病理号为%s的样本不存在于此次实验流程", experimentProcessSampleVo.getMoleculePathologyNumber()));
            }

            pcrHskzyqWzDto.setFzblh(fzblh);
            pcrHskzyqWzDto.setProject(project);

            valueSet.add((String) l.get(1));

            switch (position) {
                case "A":
                    A.set(StrUtil.drawNumberFromStr((String) l.get(0)) - 1, pcrHskzyqWzDto);
                    break;
                case "B":
                    B.set(StrUtil.drawNumberFromStr((String) l.get(0)) - 1, pcrHskzyqWzDto);
                    break;
                case "C":
                    C.set(StrUtil.drawNumberFromStr((String) l.get(0)) - 1, pcrHskzyqWzDto);
                    break;
                case "D":
                    D.set(StrUtil.drawNumberFromStr((String) l.get(0)) - 1, pcrHskzyqWzDto);
                    break;
                case "E":
                    E.set(StrUtil.drawNumberFromStr((String) l.get(0)) - 1, pcrHskzyqWzDto);
                    break;
                case "F":
                    F.set(StrUtil.drawNumberFromStr((String) l.get(0)) - 1, pcrHskzyqWzDto);
                    break;
                case "G":
                    G.set(StrUtil.drawNumberFromStr((String) l.get(0)) - 1, pcrHskzyqWzDto);
                    break;
                case "H":
                    H.set(StrUtil.drawNumberFromStr((String) l.get(0)) - 1, pcrHskzyqWzDto);
                    break;
                default:
                    break;

            }
        }
        finalList.set(0, A);
        finalList.set(1, B);
        finalList.set(2, C);
        finalList.set(3, D);
        finalList.set(4, E);
        finalList.set(5, F);
        finalList.set(6, G);
        finalList.set(7, H);

        //扩增仪数据id
        Long pcrKzyId;
        PcrKzy oldPcrKzy = this.selectByPcrIdAndDeviceId(pcrId, deviceId);
        if (Objects.isNull(oldPcrKzy)) {
            //新增
            PcrKzy insertParam = new PcrKzy();
            insertParam.setPcrId(pcrId);
            insertParam.setDeviceId(deviceId);
            insertParam.setLcbbbshkzwzData(JsonUtil.toString(finalList));
            pcrKzyId = this.insert(insertParam);
        } else {
            //修改
            oldPcrKzy.setLcbbbshkzwzData(JsonUtil.toString(finalList));
            this.update(oldPcrKzy);
            pcrKzyId = oldPcrKzy.getId();
        }

        //删除判定结果
        pcrResultService.deleteByPcrIdAndDeviceId(pcrId, deviceId);
        pcrResultDetailService.deleteByPcrIdAndDeviceId(pcrId, deviceId);

        PcrKzyVo pcrKzyVo = this.selectVoById(pcrKzyId);
        List<PcrResultDto.OneRowDto> oneRowDtoList = listList.stream().filter(l -> StringUtils.isNotBlank((String) l.get(1))).map(l -> PcrResultDto.OneRowDto.builder()
                .fyk((String) l.get(0))
                .ybmc((String) l.get(1))
                .jymc((String) l.get(2))
                .task((String) l.get(3))
                .bgjy((String) l.get(4))
                .cmjy((String) l.get(5))
                .ct(StringUtils.isNotBlank(l.get(6) + "") && !"未确定".equals(l.get(6) + "") && StrUtil.isNotNullStr(l.get(6) + "") ? new BigDecimal(l.get(6) + "") : BigDecimal.ZERO)
                .ctpjz(StringUtils.isNotBlank(l.get(7) + "") && StrUtil.isNotNullStr(l.get(7) + "") ? new BigDecimal(l.get(7) + "") : BigDecimal.ZERO)
                .ctsd(StringUtils.isNotBlank(l.get(8) + "") && StrUtil.isNotNullStr(l.get(8) + "") ? new BigDecimal(l.get(8) + "") : BigDecimal.ZERO)
                .sl(StringUtils.isNotBlank(l.get(9) + "") && StrUtil.isNotNullStr(l.get(9) + "") ? Integer.valueOf(l.get(9) + "") : 0)
                .slpjz(StringUtils.isNotBlank(l.get(10) + "") && StrUtil.isNotNullStr(l.get(10) + "") ? Integer.valueOf(l.get(10) + "") : 0)
                .slsd(StringUtils.isNotBlank(l.get(11) + "") && StrUtil.isNotNullStr(l.get(11) + "") ? Integer.valueOf(l.get(11) + "") : 0)
                .zdctyz(l.get(12))
                .ctyz(StringUtils.isNotBlank(l.get(13) + "") && StrUtil.isNotNullStr(l.get(13) + "") ? new BigDecimal(l.get(13) + "") : BigDecimal.ZERO)
                .zdjx(l.get(14))
                .jxqd(StringUtils.isNotBlank(l.get(15) + "") && StrUtil.isNotNullStr(l.get(15) + "") ? Integer.valueOf(l.get(15) + "") : 0)
                .jxzd(StringUtils.isNotBlank(l.get(16) + "") && StrUtil.isNotNullStr(l.get(16) + "") ? Integer.valueOf(l.get(16) + "") : 0)
                .zs((String) l.get(17))
                .highsd((String) l.get(18))
                .build()).collect(Collectors.toList());


        List<PcrResultDto> d1 = valueSet.stream().map(v3 -> {
            PcrResultDto pcrResultDto = new PcrResultDto();
            pcrResultDto.setYbmc(v3);
            List<PcrResultDto.OneRowDto> collect = oneRowDtoList.stream().filter(o -> o.getYbmc().equals(v3)).collect(Collectors.toList());
            Set<String> fykSet = Sets.newHashSet();
            collect.forEach(c -> fykSet.add(c.getFyk()));
            List<PcrResultDto.FYKDto> fykDtoList = Lists.newArrayList();
            fykSet.forEach(f -> {
                List<PcrResultDto.OneRowDto> collect1 = collect.stream().filter(o -> o.getFyk().equals(f)).collect(Collectors.toList());
                PcrResultDto.FYKDto fykDto = new PcrResultDto.FYKDto();
                fykDto.setFyk(f);
                fykDto.setOneRowDtoList(collect1);
                fykDtoList.add(fykDto);
            });
            pcrResultDto.setFykDtoList(fykDtoList);
            return pcrResultDto;
        }).collect(Collectors.toList());


        for (PcrResultDto d : d1) {
            List<PcrResultDto.FYKDto> fykDtoList = d.getFykDtoList();
            PcrResult pcrResult = new PcrResult();
            pcrResult.setPcrId(pcrId);
            pcrResult.setDeviceId(deviceId);
            //样本名
            String ybmc = d.getYbmc();
            String[] ybmcAry = ybmc.split("-");
            pcrResult.setProject(ybmcAry[1]);
            //样本分子病理号
            String fzblh = ybmcAry[0];
//            if (fzblh.equals(Constants.Pcr.NTC) || fzblh.equals(Constants.Pcr.STD)) {
//                //如果是NTC/STD，越过循环
//                continue;
//            }
            pcrResult.setBlh(fzblh);
            pcrResult.setPcrKzyId(pcrKzyId);
            Long resultId = pcrResultService.insert(pcrResult);
            //反应孔set
            Set<String> fykSet = fykDtoList.stream().map(PcrResultDto.FYKDto::getFyk).collect(Collectors.toSet());
            List<PcrResultDetail> pcrResultDetails = fykSet.stream().map(fykNumber -> {
                //循环反应孔序号
                PcrResultDetail pcrResultDetail = new PcrResultDetail();
                pcrResultDetail.setResultId(resultId);
                pcrResultDetail.setPcrId(pcrId);
                pcrResultDetail.setDeviceId(deviceId);
                pcrResultDetail.setPcrKzyId(pcrKzyId);
                pcrResultDetail.setFyk(fykNumber);
                //扩增曲线图文件地址
                String kzLineFilePath = this.getKzLineFilePath(fzblh, fykNumber);
                pcrResultDetail.setKzLineFilePath(kzLineFilePath);

                //数字
                Integer integer = StrUtil.drawNumberFromStr(fykNumber);
                if (ybmcAry[1].equalsIgnoreCase(KnbEnum.BRAF.name())) {
                    //如果是BRAF，突变类型就是固定的
                    pcrResultDetail.setTblx(KnPositionEnum.ZERO.getDesc());
                } else {
                    //如果是K或者N，就要根据位置判断
                    KnPositionEnum knPositionEnum = KnPositionEnum.getByCode(integer);
                    if (Objects.nonNull(knPositionEnum)) {
                        pcrResultDetail.setTblx(knPositionEnum.getDesc());
                    }
                }
                pcrResultDetail.setCreateTime(now);
                pcrResultDetail.setUpdateTime(now);
                List<PcrResultDto.FYKDto> k1 = fykDtoList.stream().filter(f -> StringUtils.isNotBlank(f.getFyk()) && f.getFyk().equals(fykNumber)).collect(Collectors.toList());
                PcrResultDto.FYKDto fykDto = k1.get(0);
                PcrResultDto.OneRowDto oneRowDto1 = fykDto.getOneRowDtoList().get(0);
                PcrResultDto.OneRowDto oneRowDto2 = fykDto.getOneRowDtoList().get(1);
                //内控CT-> KRAS excel里面的基因名称是VIC的，G列Ct值
                if (oneRowDto1.getJymc().equals("VIC")) {
                    pcrResultDetail.setNkct(oneRowDto1.getCt());
                } else if (oneRowDto2.getJymc().equals("VIC")) {
                    pcrResultDetail.setNkct(oneRowDto2.getCt());
                }
                if (integer == 12) {
                    //外控CT-> A12excel里面的基因名称是FAM的，G列Ct值
                    if (oneRowDto1.getJymc().equals("FAM")) {
                        pcrResultDetail.setWkct(oneRowDto1.getCt());
                    } else if (oneRowDto2.getJymc().equals("FAM")) {
                        pcrResultDetail.setWkct(oneRowDto2.getCt());
                    }
                } else {
                    //突变CT-> A1 - A11, 基因名称是FAM Ct(G列)
                    if (oneRowDto1.getJymc().equals("FAM")) {
                        pcrResultDetail.setTbct(oneRowDto1.getCt());
                    } else if (oneRowDto2.getJymc().equals("FAM")) {
                        pcrResultDetail.setTbct(oneRowDto2.getCt());
                    }
                }
                return pcrResultDetail;
            }).collect(Collectors.toList());
            //拿到A12 行的外控CT值，赋值给其他所有的
            List<BigDecimal> bigDecimals = pcrResultDetails.stream().filter(c -> Objects.nonNull(c.getWkct())).map(PcrResultDetail::getWkct).collect(Collectors.toList());
            List<PcrResultDetail> collect2;
            BigDecimal bigDecimal28 = new BigDecimal("28");
            BigDecimal bigDecimal25 = new BigDecimal("25");
            BigDecimal bigDecimal26 = new BigDecimal("26");
            BigDecimal bigDecimal29 = new BigDecimal("29");
            BigDecimal bigDecimal9 = new BigDecimal("9");
            BigDecimal bigDecimal10 = new BigDecimal("10");
            BigDecimal bigDecimal11 = new BigDecimal("11");
            //KNB实验，核酸扩增一区，内控ct最小值
            BigDecimal knbHskzyqNkctMin = new BigDecimal(commonConfig.getKnbHskzyqNkctMin() + "");
            //KNB实验，核酸扩增一区，内控ct最大值
            BigDecimal knbHskzyqNkctMax = new BigDecimal(commonConfig.getKnbHskzyqNkctMax() + "");
            //KNB实验，核酸扩增一区，外控ct最小值
            BigDecimal knbHskzyqWkctMin = new BigDecimal(commonConfig.getKnbHskzyqWkctMin() + "");
            //KNB实验，核酸扩增一区，外控ct最大值
            BigDecimal knbHskzyqWkctMax = new BigDecimal(commonConfig.getKnbHskzyqWkctMax() + "");
            if (CollectionUtils.isEmpty(bigDecimals)) {
                collect2 = pcrResultDetails.stream().map(c -> {
                    //突变ct
                    BigDecimal tbct = c.getTbct();
                    //28>突变ct>25，此时需要计算ΔCt值，ΔCt值=突变ct-外控ct
                    if (bigDecimal28.compareTo(tbct) == 1 && tbct.compareTo(bigDecimal25) == 1) {
                        BigDecimal wkct = c.getWkct();
                        //德尔塔CT值
                        BigDecimal ct3 = tbct.subtract(wkct);
                        c.setCt3(ct3);
                    }
                    return c;
                }).collect(Collectors.toList());
            } else {
                collect2 = pcrResultDetails;
            }
            List<PcrResultDetail> collect3;

            //外面的不合格样本列表，通过阴性室内质控与阳性室内质控来判断
            Set<ExperimentProcessSample> bhgOutList = Sets.newHashSet();

            //里面的不合格样本列表，通过内控CT来判断
            Set<ExperimentProcessSample> bhgInsideNkCtList = Sets.newHashSet();

            //里面的不合格样本列表，通过外控CT来判断
            Set<ExperimentProcessSample> bhgInsideWkCtList = Sets.newHashSet();

            if (pcrKzyVo.getJgpdyxsnzksfwr() == StatusEnum.NORMAL.getCode().byteValue() || pcrKzyVo.getJgpdyxsnzksfzk() == StatusEnum.UN_NORMAL.getCode().byteValue()) {
                //如果阴性室内质控为是，或者阳性室内质控为否，则所有样本不合格
                collect3 = collect2.stream().map(c -> {
                    c.setYyx("不合格");
                    PcrResult p = pcrResultService.selectById(c.getResultId());
                    //分子病理号
                    String blh = p.getBlh();
                    ExperimentProcessSample experimentProcessSample = experimentProcessSampleService.selectByFzblh(blh);
                    if (Objects.nonNull(experimentProcessSample) && Objects.equals(experimentProcessSample.getExperimentProcessId(), pcrId)) {
                        bhgOutList.add(experimentProcessSample);
                    }
                    return c;
                }).collect(Collectors.toList());
            } else {
                collect3 = collect2.stream().map(c -> {
                    //内控ct
                    BigDecimal nkct = c.getNkct();
                    if (Objects.nonNull(nkct)) {
                        if (nkct.compareTo(knbHskzyqNkctMin) == -1 || nkct.compareTo(knbHskzyqNkctMax) == 1) {
                            //如果内控ct不在合格范围内，则样本不合格
                            c.setYyx("不合格");
                            PcrResult p = pcrResultService.selectById(c.getResultId());
                            //分子病理号
                            String blh = p.getBlh();
                            ExperimentProcessSample experimentProcessSample = experimentProcessSampleService.selectByFzblh(blh);
                            if (Objects.nonNull(experimentProcessSample) && Objects.equals(experimentProcessSample.getExperimentProcessId(), pcrId)) {
                                bhgInsideNkCtList.add(experimentProcessSample);

                            }
                            return c;
                        }
                    }
                    //外控ct
                    BigDecimal wkct = c.getWkct();
                    if (Objects.nonNull(wkct)) {
                        if (wkct.compareTo(knbHskzyqWkctMin) == -1 || wkct.compareTo(knbHskzyqWkctMax) == 1) {
                            //如果外控ct不在合格范围内，则样本不合格
                            c.setYyx("不合格");
                            PcrResult p = pcrResultService.selectById(c.getResultId());
                            //分子病理号
                            String blh = p.getBlh();
                            ExperimentProcessSample experimentProcessSample = experimentProcessSampleService.selectByFzblh(blh);
                            if (Objects.nonNull(experimentProcessSample) && Objects.equals(experimentProcessSample.getExperimentProcessId(), pcrId)) {
                                bhgInsideWkCtList.add(experimentProcessSample);
                            }
                            return c;
                        }
                    }
                    String fyk = c.getFyk();
                    //突变ct
                    BigDecimal tbct = c.getTbct();

                    //德尔塔ct
                    BigDecimal ct3 = c.getCt3();
                    if (Objects.isNull(tbct)) {
                        return c;
                    }
//                    if (tbct.compareTo(bigDecimal26) == -1) {
//                        //所有的突变ct，如果小于26，结果就是强
//                        c.setYyx("强");
//                    } else {
                    //反应孔坐标
                    Integer fykPosition = StrUtil.drawNumberFromStr(fyk);
                    switch (fykPosition) {
                        case 1:
                            if (tbct.compareTo(bigDecimal28) == 0 || tbct.compareTo(bigDecimal28) == 1) {
                                //当突变ct>=28的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal28) == -1 &&
                                    (ct3.compareTo(bigDecimal9) == 0 || ct3.compareTo(bigDecimal9) == -1)) {
                                //当26<=突变ct<28，并且德尔塔ct<=9的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 2:
                            if (tbct.compareTo(bigDecimal29) == 0 || tbct.compareTo(bigDecimal29) == 1) {
                                //当突变ct>=29的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal29) == -1 &&
                                    (ct3.compareTo(bigDecimal10) == 0 || ct3.compareTo(bigDecimal10) == -1)) {
                                //当26<=突变ct<29，并且德尔塔ct<=10的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 3:
                            if (tbct.compareTo(bigDecimal28) == 0 || tbct.compareTo(bigDecimal28) == 1) {
                                //当突变ct>=28的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal28) == -1 &&
                                    (ct3.compareTo(bigDecimal11) == 0 || ct3.compareTo(bigDecimal11) == -1)) {
                                //当26<=突变ct<28，并且德尔塔ct<=11的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 4:
                            if (tbct.compareTo(bigDecimal29) == 0 || tbct.compareTo(bigDecimal29) == 1) {
                                //当突变ct>=29的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal29) == -1 &&
                                    (ct3.compareTo(bigDecimal10) == 0 || ct3.compareTo(bigDecimal10) == -1)) {
                                //当26<=突变ct<29，并且德尔塔ct<=10的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 5:
                            if (tbct.compareTo(bigDecimal29) == 0 || tbct.compareTo(bigDecimal29) == 1) {
                                //当突变ct>=29的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal29) == -1 &&
                                    (ct3.compareTo(bigDecimal9) == 0 || ct3.compareTo(bigDecimal9) == -1)) {
                                //当26<=突变ct<29，并且德尔塔ct<=9的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 6:
                            if (tbct.compareTo(bigDecimal28) == 0 || tbct.compareTo(bigDecimal28) == 1) {
                                //当突变ct>=28的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal28) == -1 &&
                                    (ct3.compareTo(bigDecimal10) == 0 || ct3.compareTo(bigDecimal10) == -1)) {
                                //当26<=突变ct<28，并且德尔塔ct<=10的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 7:
                            if (tbct.compareTo(bigDecimal29) == 0 || tbct.compareTo(bigDecimal29) == 1) {
                                //当突变ct>=29的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal29) == -1 &&
                                    (ct3.compareTo(bigDecimal9) == 0 || ct3.compareTo(bigDecimal9) == -1)) {
                                //当26<=突变ct<29，并且德尔塔ct<=9的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 8:
                            if (tbct.compareTo(bigDecimal29) == 0 || tbct.compareTo(bigDecimal29) == 1) {
                                //当突变ct>=29的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal29) == -1 &&
                                    (ct3.compareTo(bigDecimal10) == 0 || ct3.compareTo(bigDecimal10) == -1)) {
                                //当26<=突变ct<29，并且德尔塔ct<=10的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 9:
                            if (tbct.compareTo(bigDecimal29) == 0 || tbct.compareTo(bigDecimal29) == 1) {
                                //当突变ct>=29的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal29) == -1 &&
                                    (ct3.compareTo(bigDecimal9) == 0 || ct3.compareTo(bigDecimal9) == -1)) {
                                //当26<=突变ct<29，并且德尔塔ct<=9的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 10:
                            if (tbct.compareTo(bigDecimal29) == 0 || tbct.compareTo(bigDecimal29) == 1) {
                                //当突变ct>=29的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal29) == -1 &&
                                    (ct3.compareTo(bigDecimal10) == 0 || ct3.compareTo(bigDecimal10) == -1)) {
                                //当26<=突变ct<29，并且德尔塔ct<=10的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 11:
                            if (tbct.compareTo(bigDecimal29) == 0 || tbct.compareTo(bigDecimal29) == 1) {
                                //当突变ct>=29的时候，为阴
                                c.setYyx("阴");
                                break;
                            }
                            if (Objects.isNull(ct3)) {
                                c.setYyx("未检出");
                                break;
                            }
                            if ((bigDecimal26.compareTo(tbct) == 0 || bigDecimal26.compareTo(tbct) == -1) && tbct.compareTo(bigDecimal29) == -1 &&
                                    (ct3.compareTo(bigDecimal9) == 0 || ct3.compareTo(bigDecimal9) == -1)) {
                                //当26<=突变ct<29，并且德尔塔ct<=9的时候，为弱阳
                                c.setYyx("弱阳");
                            }
                            break;
                        case 12:
                            break;
                        default:
                            break;
                    }
//                    }
                    return c;
                }).collect(Collectors.toList());
            }
            if (CollectionUtil.isNotEmpty(bhgOutList)) {
                bhgOutList.forEach(experimentProcessSample -> experimentProcessSampleService.createNewFromBhg(experimentProcessSample, pcr));
            }
            if (CollectionUtil.isNotEmpty(bhgInsideNkCtList)) {
                bhgInsideNkCtList.forEach(experimentProcessSample -> experimentProcessSampleService.createNewFromBhg(experimentProcessSample, pcr));
            }
            if (CollectionUtil.isNotEmpty(bhgInsideWkCtList)) {
                bhgInsideWkCtList.forEach(experimentProcessSample -> experimentProcessSampleService.createNewFromBhg(experimentProcessSample, pcr));
            }
            List<PcrResultDetail> collect4 = collect3.stream().filter(Objects::nonNull).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect4)) {
                pcrResultDetailService.insertBatch(collect4);
            }
        }

        return true;
    }

    @Override
    public List<PcrOfKzyVo> selectPcrOfKzyVoByPcrId(Long pcrId) {
        List<PcrKzyVo> experimentProcessKzyVos = this.selectList(PcrKzySearchVo.builder()
                .pcrId(pcrId)
                .build());
        if (CollectionUtil.isEmpty(experimentProcessKzyVos)) {
            return Collections.emptyList();
        }
        return experimentProcessKzyVos.stream().map(experimentProcessKzyVo -> {
            Long deviceId = experimentProcessKzyVo.getDeviceId();
            PcrOfKzyVo experimentProcessOfKzyVo = new PcrOfKzyVo();
            experimentProcessOfKzyVo.setDeviceId(deviceId);
            Device device = deviceService.selectById(deviceId);
            experimentProcessOfKzyVo.setDeviceName(Objects.nonNull(device) ? device.getName() : "");
            String lcbbbshkzwzData = experimentProcessKzyVo.getLcbbbshkzwzData();
            experimentProcessOfKzyVo.setKzyData(experimentProcessKzyVo);
            List<PcrResultVo> experimentProcessResultVos = pcrResultService.selectList(PcrResultSearchVo.builder()
                    .pcrId(pcrId)
                    .deviceId(deviceId)
                    .build());
            experimentProcessOfKzyVo.setExperimentProcessResultList(experimentProcessResultVos);
            //分类后的
            List<PcrClassifyResultVo> pcrClassifyResultVos = pcrResultService.selectClassifyList(PcrResultSearchVo.builder()
                    .pcrId(pcrId)
                    .deviceId(deviceId)
                    .build());
            experimentProcessOfKzyVo.setExperimentProcessClassifyResultList(pcrClassifyResultVos);
            if (StringUtils.isNotBlank(lcbbbshkzwzData)) {
                List<List<PcrHskzyqWzDto>> parseObject = JSON.parseObject(lcbbbshkzwzData, new TypeReference<List<List<PcrHskzyqWzDto>>>() {
                });
                experimentProcessOfKzyVo.setLcbbbshkzwzDataList(parseObject);
            }
            return experimentProcessOfKzyVo;
        }).collect(Collectors.toList());
    }

    /**
     * 根据分子病理号与孔序号，获取扩增曲线图路径
     *
     * @param fzblh
     * @param sortNumber
     * @return
     */
    private String getKzLineFilePath(String fzblh, String sortNumber) {
        String kzqxPath = uploadParam.getKzqxPath();
        java.io.File file = new File(kzqxPath + fzblh);
        if (!file.exists() || !file.isDirectory()) {
            return null;
        }
        File[] files = file.listFiles();
        if (Objects.isNull(files) || files.length == 0) {
            return null;
        }
        return String.format("%s%s%s%s-%s.jpg", kzqxPath, fzblh, File.separator, fzblh, sortNumber);
    }

}